import re

from django import http
from django.contrib.auth import login
from django.shortcuts import render, redirect

# Create your views here.
from django.views import View
from QQLoginTool.QQtool import OAuthQQ
from django.conf import settings

from oauth.models import OauthQQUser
from users.models import User
from utils.signature import code_signed_openid, decode_signed_openid
from django_redis import get_redis_connection

class QQLoginView(View):
    def get(self,request):
        # 1,生成一个oauth对象
        oauth = OAuthQQ(client_id=settings.QQ_CLIENT_ID, client_secret=settings.QQ_CLIENT_SECRET,
                        redirect_uri=settings.QQ_REDIRECT_URI, state='/')
        # 2,获取url
        url = oauth.get_qq_url()
        # 3,重定向到url
        return redirect(url)

class OauthCallback(View):
    def get(self,request):
        # 1. 获取code
        code = request.GET.get('code')
        # 2. 根据code 获取 openid, 分两步
        if code:
            # 2.1,生成一个oauth对象
            oauth = OAuthQQ(client_id=settings.QQ_CLIENT_ID,
                            client_secret=settings.QQ_CLIENT_SECRET,
                            redirect_uri=settings.QQ_REDIRECT_URI,
                            state='/')
            # 2.2. 根据code 获取 accesstoken 使用 get_access_token 方法
            accesstoken = oauth.get_access_token(code)
            # 2.3. 根据accesstoken 获取 openid 使用 get_open_id 方法
            openid = oauth.get_open_id(accesstoken)
        else:
            return http.HttpResponseForbidden('code丢了!')
        try:
            qquser = OauthQQUser.objects.get(openid=openid)
        except Exception as e:
            # 加密openid
            signed_openid = code_signed_openid(openid)

            # 3. 返回绑定页面
            return render(request, 'oauth_callback.html', context={'signed_openid':signed_openid})

        # 已经绑定过的qq用户, 获取美多用户
        user = qquser.user

        # 登录美多用户
        login(request, user)

        # 保持登录状态
        request.session.set_expiry(3600*24*2)

        response = redirect('/')
        response.set_cookie('username', user.username, 3600*24*2)
        return response

    def post(self,request):
        # 1, 接收参数
        signed_openid = request.POST.get('signed_openid')
        mobile = request.POST.get('mobile')
        pwd = request.POST.get('pwd')
        sms_code = request.POST.get('sms_code')

        # 2, 校验参数
        # 2,1 判空
        if not all([signed_openid,mobile,pwd,sms_code]):
            return http.HttpResponseForbidden('参数不全')

        # 2,2 逐个校验
        # 校验 signed_openid
        openid = decode_signed_openid(signed_openid)
        print(openid)
        if not openid:
            return http.HttpResponseForbidden('openid非法')
        # 校验 mobile
        if not re.match(r'^1[345789]\d{9}$', mobile):
            return http.HttpResponseForbidden('手机号码有误')
        # 校验 pwd
        if not re.match(r'^[0-9A-Za-z]{8,20}$', pwd):
            return http.HttpResponseForbidden('密码格式有误')
        # 校验 sms_code
        redis_conn = get_redis_connection('sms_code')
        redis_sms_code = redis_conn.get(mobile).decode()
        if sms_code != redis_sms_code:
            return http.HttpResponseForbidden('短信验证码有误')


        # 3, 判断是否存在使用这个号码注册的用户
        try:
            user = User.objects.get(mobile=mobile)
        except User.DoesNotExist:
            # 4, 不存在此用户 , 注册用户进行绑定
            user = User.objects.create_user(username=mobile, password=pwd, mobile=mobile)
            OauthQQUser.objects.create(openid=openid, user=user)
        else:
            # 5, 存在此用户, 进行绑定
            # 5,1 如果用户存在, 要判断一下用户的密码是否正确
            if user.check_password(pwd):
                OauthQQUser.objects.create(openid=openid, user= user)
            else:
                return http.HttpResponseForbidden('密码不正确')

        # 6 绑定后逻辑完善
        # 6,1 登录
        login(request, user)
        # 6,2 持久化
        request.session.set_expiry(3600*24*2)
        # 6,3 写cookie
        response = redirect('/')
        response.set_cookie('username', user.username, expires=3600*24*2)

        # 6,4 重定向到首页
        return response




